from collections import defaultdict

def add_conditions_to_bpmn_flows(bpmn, sequence_json):
    """
    为 bpmn 的 sequence flows 增加 label（来自 sequence_json 的 condition）。
    假设：同一 (src, tgt) 在 sequence_json 中可能出现多次（有多个条件），
    将按 sequence_json 的顺序逐条分配给 BPMN 中对应的 SequenceFlow 列表（同一 src,tgt 可能有多条 flow）。
    返回命中的连线数量。
    """
    def condition_to_text(cond):
        if cond in (None, "", "无"):
            return None
        if isinstance(cond, dict):
            return cond.get("manuscript_state")
        return str(cond)

    # 1) 构建 (src, tgt) -> [cond1, cond2, ...]
    cond_map = defaultdict(list)
    for rec in sequence_json:
        src = str(rec.get("now_state", "")).strip()
        tgt = str(rec.get("next_state", "")).strip()
        ctext = condition_to_text(rec.get("condition"))
        if src and tgt and ctext is not None:
            # 只对网关节点的流出添加条件标签到BPMN图
            if src.startswith('exclusiveGateway') or src.startswith('parallelGateway'):
                cond_map[(src, tgt)].append(ctext)
    print("###########条件表", cond_map)
    # 2) 把 bpmn 中的 flows 按 (src_name_or_id, tgt_name_or_id) 分组
    flows_by_key = defaultdict(list)
    for flow in bpmn.get_flows():
        src_name = getattr(flow.source, "name", None) or getattr(flow.source, "id", None) or ""
        tgt_name = getattr(flow.target, "name", None) or getattr(flow.target, "id", None) or ""
        key = (str(src_name).strip(), str(tgt_name).strip())
        flows_by_key[key].append(flow)

    # 3) 对每个 key，按顺序分配条件（1:1）
    hits = 0
    for key, flows in flows_by_key.items():
        if key not in cond_map:
            continue
        conds = cond_map[key]
        # 逐一对应分配，按最小长度分配
        for flow, cond in zip(flows, conds):
            flow.label = cond
            hits += 1
            print("增加名字标签", flow.source.name, "->", flow.target.name, ":", flow.label)

        # 如果期望严格 1:1 （条件数必等于 flows 数），
        # 可以在这里检测并提醒（目前不抛异常，保持兼容性）
        if len(conds) != len(flows):
            print(f"警告: key={key} 条件数 {len(conds)} != flow 数 {len(flows)}")

    return hits